home *** CD-ROM | disk | FTP | other *** search
- /*
- * ostape.c: reads OS standard labeled tapes, using dd to do the real work.
- *
- * Usage: ostape
- *
- * Christine Gianone, CUCCA, December 1986
- *
- */
-
- /* Preprocessor Stuff */
-
- #include <stdio.h>
- #include <ctype.h>
-
- #define MAXLEN 90 /* Max length for a label line */
- #define MAXFN 17 /* Max length for filename */
-
- #define XVOL1 0 /* Symbols for label identifiers */
- #define XEOV1 1
- #define XHDR1 2
- #define XHDR2 3
- #define XEOF1 4
- #define XEOF2 5
- #define XUVL1 6
- #define XUHL1 7
- #define XUTL1 8
-
- /* Global Declarations */
-
- char buff[MAXLEN]; /* Input line buffer */
- FILE *fp, *fopen(); /* File pointer & open function */
-
- struct lbl { /* Label ids and case indexes */
- char *id;
- int code;
- };
-
- struct lbl tbl[10] = {
- "VOL1", XVOL1, /* Volume label */
- "EOV1", XEOV1, /* End-of-Volume */
- "HDR1", XHDR1, /* Header 1 */
- "HDR2", XHDR2, /* Header 2 */
- "EOF1", XEOF1, /* End of file 1 */
- "EOF2", XEOF2, /* and 2 */
- "UVL1", XUVL1, /* User labels */
- "UHL1", XUHL1, /* are */
- "UTL1", XUTL1 /* ignored... */
- };
-
- int nids = (sizeof(tbl) / sizeof(struct lbl));
-
- extern int errno; /* System error stuff */
- extern char *sys_errlist[];
-
- char vn[6]; /* Volume name */
- char fn[MAXFN]; /* File name */
- int bs; /* Blocksize */
- int rl; /* Record length */
- int bc; /* Block count in EOF1 */
- char rf; /* Record format */
-
- char *ddhdr = "dd if=/dev/rmt12 of=hdr.tmp ibs=800 cbs=80 conv=unblock,ascii";
-
- /* Main function */
-
- main(argc,argv)
- int argc; /* Command line arguments */
- char *argv[]; /* (not used) */
- {
- int x; /* Declare local variables */
- int files = 0; /* Files processed */
- int skip = 0; /* Files skipped */
- char ddcmd[200];
-
- for (files = 0 ; ; )
- {
- unlink("hdr.tmp"); /* Delete temp header file */
- system(ddhdr);
-
- if ((x = phdr()) < 0) /* Process the header */
- break;
- else if (x == 0)
- {
- printf("dd cannot read %s in %c format", fn, rf);
- system("mt fsf 2"); /* Skip forward 2 files */
- skip++; /* to next tape header. */
- continue;
- }
- sprintf(ddcmd,
- "dd if=/dev/rmt12 of=%s ibs=%d cbs=%d conv=unblock,ascii",
- fn,bs,rl);
- system(ddcmd); /* Run the dd command above */
- sprintf(ddcmd, "ls -l %s", fn); /* to read the tape file */
- files++; /* Count the file. */
- system(ddcmd); /* Run the list command above */
-
- unlink("eof.tmp"); /* Delete old temp trailer file */
- system(ddhdr);
-
- if ((x = peof()) < 0) /* Process trailer labels */
- break;
- }
- unlink("hdr.tmp");
- unlink("eof.tmp");
- printf("All done! Files Read: %d -- Files Skipped: %d\n", files, skip);
-
- }
-
- /* Process a header ... */
- /* Returns 1 valid file header with recfm F, */
- /* 0 if valid file header with some other recfm (which dd can't handle), or */
- /* -1 otherwise - fatal error or end of tape */
-
- phdr()
- {
- int i, j, k, l = 0;
- char c;
-
- *fn=bs=rl=rf=0; /* Initialize file variables */
- fp = fopen("hdr.tmp", "r"); /* Try to open header file */
- if (fp == NULL) /* Check for errors */
- {
- printf("%s\n",sys_errlist[errno]); /* Oops, can't... */
- return(-1);
- }
- while (fgets(buff, MAXLEN, fp) != NULL) /* Read each line */
- {
- switch (k = lookup()) { /* Got line, look up label id */
- case XVOL1: /* VOL1 */
- buff[10] = 0;
- printf("VOL: '%s'\n", buff+4); /* Print volid */
- break;
-
- case XEOV1: /* End of volume */
- printf("End of volume\n");
- return(-1);
-
- case XHDR1: /* File header 1 */
- for (i = 0; i < MAXFN; i++) /* Copy name */
- {
- c = buff[i+4]; /* and convert to lower case */
- fn[i] = isupper(c) ? tolower(c) : c;
- }
- for (i = MAXFN - 1; i > 0; i--) /* Trim trailing blanks */
- {
- if (fn[i] == ' ')
- fn[i] = '\0';
- else break;
- }
- printf("Filename: '%s'\n", fn); /* Print the name */
- break;
-
- case XHDR2: /* File header 2 */
- buff[15] = 0;
- rl = atoi (buff + 10); /* Record length */
- buff[10] = 0;
- bs = atoi (buff + 5); /* Block size */
- rf = buff[4]; /* Record format */
- printf ("rl: %d, bs: %d, rf: %c\n", rl, bs, rf);
- break;
-
- case XUVL1: /* User headers */
- case XUHL1: /* (ignored) */
- break;
-
- default:
- printf("Unexpected ID header label:\n%s\n",buff);
- if(++l > 3) /* Give up if too many, */
- return(-1); /* probably not real headers */
- break;
- }
- }
- if (fclose(fp) == EOF) /* Close the file */
- {
- printf("%s\n",sys_errlist[errno]);
- return(-1);
- }
- if (*fn != '\0' ) /* If we have a filename */
- return((rf == 'F') ? 1 : 0); /* return 1 or 0 based on recfm */
- else return(-1); /* otherwise probably end of tape */
- }
-
- /* Process trailer labels... */
- /* Returns -1 if the trailer label is invalid, otherwise 0. */
-
- peof()
- {
- int i, j, k, l = 0; /* Local variables */
- char c;
- bc = 0; /* Block count */
-
- fp = fopen("eof.tmp", "r"); /* Try to open trailer label file */
- if (fp == NULL) /* Check for errors */
- {
- printf("%s\n",sys_errlist[errno]);
- return(-1);
- }
- while (fgets(buff, MAXLEN, fp) != NULL) /* Read each line */
- {
- switch (k = lookup()) /* Got line, look up label id */
- {
- case XEOF1: /* End of file 1 */
- buff[60] = 0;
- bc = atoi (buff + 54); /* Get block count & print it */
- printf("EOF: %d block%c\n", bc, (bc == 1) ? ' ' : 's');
- break;
-
- case XEOV1: /* End of volume */
- printf("End of volume");
- return(-1);
-
- case XEOF2: /* End of file 2 */
- break;
-
- case XUTL1: /* User trailer */
- break; /* (ignored) */
-
- default:
- printf("Unexpected ID in trailer label:\n%s\n",buff);
- if (++l > 3) /* If too many unknowns, */
- return(-1); /* probably not a real trailer. */
- break;
- }
- }
- if (fclose(fp) == EOF) /* Close the file */
- {
- printf("%s\n",sys_errlist[errno]);
- return(-1);
- }
- return(0);
- }
-
- /* Lookup */
-
- lookup() /* Look up label ID, */
- { /* return case index, or -1. */
- int i, j;
-
- for (j = 0; j < nids; j++) /* For each ID in our list (row) */
- {
- for (i = 0; i < 4; i++) /* Compare each character (column) */
- {
- if (buff[i] != tbl[j].id[i]) /* If chars differ, */
- break; /* then try next row, */
- else continue; /* otherwise keep comparing. */
- }
- if (i == 4) return (tbl[j].code); /* i is 4 if all chars match. */
- }
- return (-1); /* No match, return -1. */
- }
-